﻿using Autofac;
using Autofac.Builder;
using AutoRegistDependency.Component;
using AutoRegistDependency.Enum;
using AutoRegistDependency.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AutoRegistDependency.RegistrationHandler
{
    /// <summary>
    /// 泛型bean处理
    /// Generic bean processing
    /// </summary>
    internal class GenericBeanHandler : AbstractRegistrationHandler
    {
        public override bool CanRegister(ComponentDefinition component)
        {
            if (component.ComponentType == ComponentType.Bean)
            {
                BeanDefinition beanComponent =(BeanDefinition)component;
                return beanComponent.CanRegist && beanComponent.IsGeneric;
            }
            else
            {
                return false;
            }
        }

        protected override IRegistrationBuilder<object, object, object> Register(ContainerBuilder containerBuilder, ComponentDefinition component)
        {
            BeanDefinition beanComponent = (BeanDefinition)component;
            var r = containerBuilder.RegisterGeneric((context, types,parameters) =>
            {
                var configurationInstance = context.Resolve(beanComponent.LocationType);
                var beanInstance = AutoFacHelper.InvokeMethod(configurationInstance, beanComponent.BeanCreatedMethod.GetGenericMethodDefinition().MakeGenericMethod(types), context, parameters,beanComponent.IsAsync);
                return beanInstance;
            });
            return r;
        }
        protected override void RegistrationAs(IRegistrationBuilder<object, object, object> registrationBuilder, ComponentDefinition component,Type[] types)
        {
            BeanDefinition beanComponent = (BeanDefinition)component;
            base.RegistrationAs(registrationBuilder,component,types.Select(t => t.GetGenericTypeDefinition()).ToArray());
        }
    }
}
